using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Yukisky.CommonUtils;

namespace Yukisky.IdentifyUser.AntiAddicted
{
    public class DefaultAntiAddictedService : IAntiAddictedServices
    {
        //每天游玩的时间
        public Dictionary<string, int> playedTime;
        //每月充值累计
        private Dictionary<string, int> chargeMonthly;

        private static string ANTIADDICTED_TIME = "anti_addicted_time";
        private static string ANTIADDICTED_COST = "anti_addicted_cost";

        public DefaultAntiAddictedService()
        {
            //在线时长
            string savedTime = IdentifyMgr.GetDBServices().GetString(ANTIADDICTED_TIME, "");
            if ( string.IsNullOrEmpty(savedTime) )
            {
                playedTime = new Dictionary<string, int>();
            }
            else
            {
                playedTime = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, int>>(savedTime);
            }
            //消费
            string savedCharge = IdentifyMgr.GetDBServices().GetString(ANTIADDICTED_COST, "");
            if ( string.IsNullOrEmpty(savedCharge) )
            {
                chargeMonthly = new Dictionary<string, int>();
            }
            else
            {
                chargeMonthly = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, int>>(savedCharge);
            }
            
        }

        public void AddTime(int time)
        {
            DateTime date = Utils.GetTime();
            var day = $"{date.Year}.{date.Month}.{date.Day}";
            if (playedTime.ContainsKey(day))
            {
                playedTime[day] = playedTime[day] + time;
            }
            else
            {
                playedTime[day] = time;
            }
            Save();
            callback?.Invoke(playedTime[day]);
        }

        public void MinusTime(int time)
        {
            DateTime date = Utils.GetTime();
            var day = $"{date.Year}.{date.Month}.{date.Day}";
            if (playedTime.ContainsKey(day))
            { 
                playedTime[day] = playedTime[day]-time;
                if (playedTime[day]<0)
                {
                    playedTime[day] = 0;
                }
            }
            Save();
            callback?.Invoke(playedTime[day]);
        }

        public int GetPlayedTime()
        {
            DateTime date = Utils.GetTime();
            var day = $"{date.Year}.{date.Month}.{date.Day}";
            if (playedTime.ContainsKey(day))
            {
                return playedTime[day];
            }

            return 0;
        }

        public void AddCharge(int money)
        {
            DateTime date = Utils.GetTime();
            var month = $"{date.Year}.{date.Month}";
            AddCharge(money,month);
        }
        
        public void AddCharge(int money,string month)
        {
            if (chargeMonthly.ContainsKey(month))
            {
                chargeMonthly[month] = chargeMonthly[month] + money;
            }
            else
            {
                chargeMonthly[month] = money;
            }
            Save();
        }

        public void MinusCharge(int money)
        {
            DateTime date = Utils.GetTime();
            var month = $"{date.Year}.{date.Month}";
            MinusCharge(money,month);
        }
        public void MinusCharge(int money,string month)
        {
            if (chargeMonthly.ContainsKey(month))
            { 
                chargeMonthly[month] = chargeMonthly[month]-money;
                if (chargeMonthly[month]<0)
                {
                    chargeMonthly[month] = 0;
                }
            }
            Save();
        }
        
        public int GetCharge()
        {
            DateTime date = Utils.GetTime();
            var month = $"{date.Year}.{date.Month}";
            if (chargeMonthly.ContainsKey(month))
            {
                return chargeMonthly[month];
            }

            return 0;
        }
        
        
        public void StartGame()
        {
            UnityMainThreadDispatcher.Instance().Enqueue(UpdateTime());
        }

        IEnumerator UpdateTime()
        {
            var step = new WaitForSecondsRealtime(60);
            while (true)
            {
                yield return step;
                Add1Minute();
            }
        }

        public void Add1Minute()
        {
            string day = string.Empty;
            DateTime date = Utils.GetTime();
            day = $"{date.Year}.{date.Month}.{date.Day}";
            if (playedTime.ContainsKey(day))
            {
                playedTime[day] = playedTime[day] + 1;
            }
            else
            {
                playedTime.Add(day,1);
            }
            callback?.Invoke(playedTime[day]);

            Save();
        }

        private void Save()
        {
            IdentifyMgr.GetDBServices().SetString(ANTIADDICTED_TIME, Newtonsoft.Json.JsonConvert.SerializeObject(playedTime) ,false);
            IdentifyMgr.GetDBServices().SetString(ANTIADDICTED_COST, Newtonsoft.Json.JsonConvert.SerializeObject(chargeMonthly) , false);
            IdentifyMgr.GetDBServices().PersistData();
        }

        public event Action<int> callback;
        public void AddListener(Action<int> func)
        {
            callback += func;
        }

        public void RemoveListener(Action<int> func)
        {
            callback -= func;
        }
    }
}